package estadistec.logica.dependencias;

import estadistec.excepciones.ExcepcionLlaveExistente;
import estadistec.excepciones.ExcepcionLlaveInexistente;
import estadistec.logica.gestores.IManejable;

/**
 * Gestionable del cual depende otro gestionable. Es el observado.
 */
public interface ISuperior <M extends IDependiente> 
	extends IManejable
{

	/**
	 * Agrega al dependiente a la lista de dependientes.
	 * 
	 * @param dependiente
	 *            A ser insertado
	 * @throws ExcepcionLlaveExistente
	 *             Si el dependiente ya fue insertado. Se verifica
	 *             utilizando la llave del mismo.
	 */
	public void agregarDependiente(M dependiente) 
		throws ExcepcionLlaveExistente;

	/**
	 * Quita al dependiente de la lista de dependientes.
	 * 
	 * @param dependiente
	 *            Llave del dependiente que va a ser eliminado de la lista de 
	 *            dependientes.
	 * @throws ExcepcionLlaveInexistente
	 *             Si <em>dependiente</em> no se encuentra en la lista de
	 *             dependientes.
	 */
	void quitarDependiente(Long dependiente) 
		throws ExcepcionLlaveInexistente;

	/**
	 * Revisa si un objeto tiene otros objetos dependientes a él.
	 * 
	 * @return True si existe al menos un objeto que depende de este.
	 */
	boolean tieneDependientes();

	/**
	 * Al haber algún cambio en un objeto, se debe notificar a todos los
	 * dependientes sobre el cambio para actualizar los datos de los mismos.
	 */
	void actualizarDependientes();

	/**
	 * Verifica si se haría un ciclo con el nuevo objeto.
	 * 
	 * @param llave
	 *            del objeto hacia el cual va dirigida la dependencia (lectura).
	 * @return True va a existir ciclo.
	 */
	boolean existeCiclo(Long llave);

}
